#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define maxn 50200
/*-----------------------------------最大流dinic模板---------------------------------------*/

#define maxv 2200//10000K最大就能开到这个数.
#define maxe 200000
#define inf 0x7fffffff
#define pb push_back
#define sz(x) (int)x.size()
int E[maxe],Ef[maxe],next[maxe],C[maxe],M,is[maxe],low[maxe],up[maxe];//is表示是原图的边，low是下界，up是上界
int first[maxv],L[maxv],Q[maxv],N,in[maxv];//in表示为点的入度，用来建立从新源和新汇连边的容量问题
int S,T;//一定要小心S,T不要在main里面再次申明
int vec;//要每次初始化的点
void __insert(int a,int b ,int c,int d,int x)
{
//a 是边起点，b是边的终点，c是下界，d是上界，x为1表示为原图的边，0表示是增加的边
    M++;
    C[M]=d-c;
    E[M]=b;
    Ef[M]= a;
    next[M]=first[a];
    first[a]=M;
    is[M]=x;
    low[M]=c;
    up[M]=d;
}
//要注意这样传很多个元素很容易超时
void insert(int a,int b,int c,int d,int x)
{
	if(!(a==S || b==T))
	{//判断点连边容量,注意新源和新汇不能连边
		if(c==inf)//注意下界传入无穷大特判以免溢出
		{
			in[a]=-c;
			in[b]=c;
		}
		else
		{
			in[a]-=c;
			in[b]+=c;
		}
	}
//a 是边起点，b是边的终点，c是下界，d是上界，x为1表示为原图的边，0表示是增加的边
    __insert(a,b,c,d,x);
    __insert(b,a,0,0,0);
}
bool bfs()
{
    int h,t,e,u,v,i;
    h=t=0;
    Q[t++]=S;
  	for(i=0; i<=vec; i++)
  		L[i] =0;

    L[S]=1;
    while(h<t)
    {
        u=Q[h++];
        for(e=first[u]; e!=-1; e=next[e])
        {
            v=E[e];
            if(L[v]==0 && C[e]>0)
            {
                L[v]=L[u]+1;
                Q[t++]=v;
            }
        }
    }
    return L[T];
}

int dfs(int u,int  f)//这个地方增广应该不会超int 界
{
	if( u == T)	return f;
	int t,e,v, w = 0;
	for(e = first[u]; e!=-1 && w<f; e=next[e])
	{
		v = E[e];
		if(C[e]>0 && L[v] == L[u] + 1)
		{
			if(t = dfs(E[e], min(C[e],f-w)))//t  要赋值
			{
				C[e] -= t;
				C[e^1] += t;
				w += t;
			}
		}
	} 
	if(!w) L[u] = -1;
	return w;
}
int dinic()
{
	int f=0, now;
	while(bfs())
	{
		now = dfs(S,inf);
		f = f + now;
	}
	return f;
}

void init(int all,int a,int b)
{
	M=-1;
	vec=all;
	S=a;T=b;
	memset(in,0,sizeof(in));
	for(int i=0; i<=vec; i++)
	{
		first[i] =-1;
		in[i]=0;
	}
}
/*------------最大流dinic模板--------------------*/
int n,m;
int a[maxn],b[maxn];
int main()	
{
	int i,j,k;
	while(scanf("%d%d", &n,&m)!=EOF)
	{
		int s=0,t=n+2;
		int x,y,p,q;
/*------------最大流dinic模板-----------------------*/
		init(n+4,0,n+2);
/*------------最大流dinic模板----------------*/
		memset(a,0,sizeof(a));
		for(i=1; i<=m; i++)
		{
			scanf("%d%d%d%d",&x,&y,&p,&q);
/*------------最大流dinic模板----------------*/
			insert(x,y,p,q,1);
/*------------最大流dinic模板----------------*/
		}
		int sum=0;
		/**********新源和新汇和点连边****************/
		for(i=1; i<=n; i++)
		if(in[i]>0)
		{
			sum+=in[i];
			insert(s,i,0,in[i],0);
		}
		else	insert(i,t,0,-in[i],0);
	/**********新源和新汇和点连边****************/
		int ans=dinic();
		if(sum!=ans)
			puts("NO");
		else
		{
			puts("YES");
			for(i=0; i<=M; i++)
			if(is[i])
			{
				int now=C[i^1]+low[i];
				printf("%d\n",now);
			}
		}
	}
}


